/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package au.com.gworks.jump.app.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.apache.log4j.Logger;
import org.javaongems.runtime.util.PropertiesUtils;
import org.javaongems.server.PrincipalUtils;

import au.com.gworks.jump.system.ApplicationManager;


final public class Bootstrap implements 	ServletContextListener,
											HttpSessionListener {
	final static public String APPL_CTX = "application.contexts";
	final static public String TOGGLE_CTX = "toggle.contexts";
	final static public String SWITCH_CTX = "switch.contexts";
	final static public String PLUGIN_CLSS = "plugin.classes";

	final static public String BOOTSTRAP_PLUGIN = "bootstrap-plugin";
	final static public int GUEST_TIMEOUT = 60 * 15;
    final static private Logger LOGGER = Logger.getLogger(Bootstrap.class);
	static private Bootstrap singleton;
	
	private ServletContext context;
	
	public Bootstrap() {
		singleton = this;
	}

	static public Bootstrap getInstance() {
		return singleton;
	}

	/* Application Startup Event */
	public void contextInitialized(ServletContextEvent ce) {
		context = ce.getServletContext();
		initializeContexts(context);
		ApplicationMimeTypeQuerier appMimeTypeQuerier = new ApplicationMimeTypeQuerier();
		ApplicationManager.setMimeType(appMimeTypeQuerier);
		LOGGER.info("user.dir=" + System.getProperty("user.dir"));
		LOGGER.info("user.home=" + System.getProperty("user.home"));
		BootstrapPlugin loader = (BootstrapPlugin) EnvironmentUtils.getPlugin(BOOTSTRAP_PLUGIN);
		if (loader != null)
			loader.load();
	}

	private void initializeContexts(ServletContext sc) {
		Properties appCtx = PropertiesUtils.toProperties(sc.getInitParameter(APPL_CTX));
		Properties toggleCtx = PropertiesUtils.toProperties(sc.getInitParameter(TOGGLE_CTX));
		Properties switchCtx = PropertiesUtils.toProperties(sc.getInitParameter(SWITCH_CTX));
		Properties pluginsCtx = PropertiesUtils.toProperties(sc.getInitParameter(PLUGIN_CLSS));
		Map pluginImpl = constructPluginClasses(pluginsCtx);
		EnvironmentUtils.initialiseApplicationContexts(appCtx, toggleCtx, switchCtx, pluginImpl);
		String val = EnvironmentUtils.getApplicationContext();
		ApplicationManager.setWebApplicationContext(val);
	}
	
	private Map constructPluginClasses(Properties props) {
		HashMap ret = new HashMap();
		for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String ClzAsStr = (String) props.get(name);
			try {
				Class Clz = Class.forName(ClzAsStr);
				Object plugin = Clz.newInstance();
				ret.put(name, plugin);
			} catch (Exception err) {
				LOGGER.error("unable to initialise plugin", err);
			}
		}
		return ret;
	}

	/* Application Shutdown Event */
	public void contextDestroyed(ServletContextEvent ce) {
		// nothing to do.
	}

	public void sessionCreated(HttpSessionEvent p0) {
		HttpSession session = p0.getSession();
		int timeout = session.getMaxInactiveInterval();
		if (timeout != GUEST_TIMEOUT)
			session.setMaxInactiveInterval(GUEST_TIMEOUT);
		timeout = session.getMaxInactiveInterval();
	}

	public void sessionDestroyed(HttpSessionEvent p0) {
		HttpSession session = p0.getSession();
		session.setAttribute(PrincipalUtils.SESS_PRINCIPAL, null);
		session.removeAttribute(PrincipalUtils.SESS_PRINCIPAL);
	}

	private class ApplicationMimeTypeQuerier implements ApplicationManager.MimeTypeQuerier {
		public String getMimeType(String fileName) {
			return context.getMimeType(fileName.toLowerCase());
		}
	}
}
